<?php

namespace common\components;

use yii\base\Component;
use common\tools\Util;

/**
 * Desc 写日志组件
 * @author HUI
 */
class WriteLog extends Component {

    /**
     * 写日志
     * @param string $name 日志文件名-[/order/info]
     * @param string $title 日志标题
     * @param string/array $info 日志内容
     * @param string $type 日志类型-['DEBUG', 'INFO', 'WARNING', 'ERROR']
     * * */
    public function log($name, $title, $info, $type = 'INFO') {
        try {
            if (empty($name) || empty($title) || empty($info)) {
                throw new \Exception('参数异常');
            }
            $dir = \Yii::$app->params['LOG_PATH'] . '/' . date('Ymd');
            if (strpos($name, '/') !== false) {
                $dir = \Yii::$app->params['LOG_PATH'] . '/' . date('Ymd') . dirname($name);
                $name = basename($name);
            }
//            //创建目录
            Util::mkdir($dir);
            //获取调用日志文件的位置
            $backtrace = $this->getActionPath(debug_backtrace());
            
            $str = date('Y-m-d H:i:s') . '[' . $type . '] ' . $backtrace . ' ' . Util::getIp() . ' [' . $title . ']';
            $content = $this->getContent($info);
            $str .= ' == ' . $content;
            $this->write($str, $dir . '/' . $name . '.log');
            return '';
        } catch (\Exception $exc) {
            return $exc->getMessage();
        }
    }
    
    /**
     * 获取到上一级执行的类名::方法 或者 文件名::行号
     * **/
   private function getActionPath($arr) {
        if (isset($arr[1])) {
            if (isset($arr[1]['class'])) {
                $class = $arr[1]['class'];
                $function = $arr[1]['function'];
            } else {
                $class = basename($arr[1]['file']);
                $function = $arr[1]['line'];
            }
        } else { // 取文件名和行号
            $class = basename($arr[0]['file']);
            $function = $arr[0]['line'];
        }
        return $class . '::' . $function;
    }
    
    /**
     * 写入日志
     * **/
   private function write($content, $name) {
        $fp = fopen($name, "a");
        flock($fp, LOCK_EX);
        fwrite($fp, preg_replace('/(\r\n)|\r|\n/', ' ', $content) . "\r\n");
        flock($fp, LOCK_UN);
        fclose($fp);
        return '';
    }
    
    /**
     * 日志内容处理
     * **/
   private function getContent($info) {
        if (!is_array($info)) {
            return $info;
        }
        $arr = array();
        foreach ($info as $k => $v) {
            $v = is_array($v) ? json_encode($v, 320) : $v;
            $arr[] = is_numeric($k) ? $v : ($k . ':' . $v);
        }
        $content = implode(' || ', $arr);
        return $content;
    }

}
